<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Ruby Gems: Ruby Study Notes - Best Ruby Guide, Ruby Tutorial</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<meta name="description" content="Ruby Study Notes - Best Ruby Guide, Ruby Tutorial" />
<meta name="keywords" content="ruby gems,ruby study notes,free ruby programming guide,ruby guide,free ruby programming course,best ruby guide,ruby tutorials,ruby tutorial,learn ruby,ruby,ruby on rails,ruby rails,ruby learning,ruby tutoring,learning ruby,ruby programming,ruby on rails development,ruby training" />
<meta name="Distribution" content="Global" />
<meta name="author" content="Satish Talim / Original design: Erwin Aligam - ealigam@gmail.com" />
<meta name="copyright" content="Satish Talim 2007 and beyond..." />
<meta name="verify-v1" content="rFu86se+IkbtF+bH8mgJBKwU5HnKaSd8Ghw9umXQOkM=" />
<meta name="robots" content="index,follow" />
<meta http-equiv="Expires" content="0" />
<meta name="revisit-after" content="1 days" />
<link rel="stylesheet" href="/images/NewOrange.css" type="text/css" />
<link rel="stylesheet" href="/images/syntaxhighlighter.css" type="text/css" />
<!-- Google +1 button code -->
<link rel="canonical" href="/satishtalim/ruby_gems.html" />
<script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script>

<!-- Google Analytics code -->
<script type="text/javascript">

  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-59044-10']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();

</script>
<!-- Google Analytics code ends -->

</head>

<body>
<!-- wrap starts here -->
<div id="wrap">

    <div id="header">

        <h1 id="logo">Ruby<span class="orange">Learning.github.io</span></h1>
        <h2 id="slogan">Helping Ruby Programmers become Awesome!</h2>

    </div>

    <div id="menu">
        <ul>
            <li><a href="/" title="Home page for rubylearning.github.io">Home</a></li>
            <li><a href="/satishtalim/tutorial.html" title="Get started Learning Ruby here...">Tutorial</a></li>
            <li><a href="/download/downloads.html" title="Download this tutorial as an eBook">Downloads</a></li>
            <li><a href="/other/testimonials.html" title="People around the world who benefited from this site">Testimonials</a></li>
            <li><a href="/other/certification.html" title="Get certified in Ruby">Certification</a></li>
            <li><a href="/satishtalim/ruby_guide.html" title="Ruby Guide, Mentor">Mentor</a></li>
            <li><a href="/blog/" title="Ruby blog of Learning Ruby site">Blog</a></li>
            <li><a href="/satishtalim/tutorial.html" title="Online Ruby Course">Online Course</a></li>
            <li><a href="http://ruby-challenge.rubylearning.org/" title="Ruby Programming Challenge for Newbies">Challenge</a></li>
            <li><a href="/satishtalim/about.html" title="Information about Satish Talim">About</a></li>
        </ul>
    </div>

    <!-- content-wrap starts here -->
    <div id="content-wrap">

            <div id="main">

                <div id="main-inner"><a name="TemplateInfo"></a>
                <h1>Distributing and Releasing Ruby Libraries As Gems</h1>

                <p>(The text below is adapted from Peter Cooper's book - <em>Beginning Ruby</em>.)<br /><br />To solve various problems with Ruby, you might develop your own libraries. Also, you might want to open-source your libraries to get community input and a larger developer base.<br /><br />RubyGems, is a library installation and management system for Ruby. With RubyGems it is easy to create "gems" of your own from your own code.</p>

                <h3>Creating a Gem</h3>

                <p>Let's first create a simple library that extends the <strong>String</strong> class and puts it in a file called string_extend.rb:</p>

                <div class="column2">
                <!-- InstanceBeginEditable name="Code" -->
                <textarea name="code" class="ruby:nogutter:nocontrols" rows="15" cols="60">
                # stringextend.rb
                class String
                  def writesize
                    puts self.size
                  end
                end
                size_writer = "Tell me my size!"
                size_writer.writesize
                </textarea>
                <!-- InstanceEndEditable -->
                </div>

                <p>This code adds a writesize method to the <strong>String</strong> class, which returns the size of the string.<br /><br />As a local library within the scope of a larger application, it could be loaded with <strong>require</strong>:</p>

                <div class="column2">
                <!-- InstanceBeginEditable name="Code" -->
                <textarea name="code" class="ruby:nogutter:nocontrols" rows="15" cols="60">
                require 'string_extend'
                </textarea>
                <!-- InstanceEndEditable -->
                </div>

                <p>However, you want to turn it into a gem that you can use anywhere. Building a gem involves three steps.</p>

                <ul>
                  <li>The first is to organize your code and other files into a structure that can be turned into a gem.</li>
                  <li>The second is to create a specification file that lists information about the gem.</li>
                  <li>The third is to use the gem program to build the gem from the source files and the specification.</li>
                </ul>

                <h3>Structuring Your Files</h3>

                <p>First, it's necessary to create a folder to contain all the gem's folders, so you create a folder called string_extend. Under this folder you create several other folders as follows:</p>

                <ul>
                  <li>lib: This directory will contain the Ruby code related to the library.</li>
                  <li>pkg: This is a temporary directory where the gem will be generated.</li>
                  <li>test: This directory will contain any unit tests or other testing scripts related to the library.</li>
                  <li>doc: This is an optional directory that could contain documentation about the library, particularly documentation created with or by rdoc.</li>
                  <li>bin: This is another optional directory that can contain system tools and command line scripts that are related to the library. For example, RubyGems itself installs the gem command line tool; such a tool would be placed into bin.</li>
                </ul>

                <p>At a minimum, you should end up with string_extend/lib, string_extend/pkg, and string_extend/test.<br /><br />In this example, you should place string_extend.rb within the string_extend/lib directory. If you have tests, documentation, or command line scripts, place them into the respective directories.</p>

                <h3>Creating a Specification File</h3>

                <p>Once your files are organized, it's time to create a specification file that describes the gem and provides RubyGems with enough information to create the final gem. Create a text file called string_extend.gemspec in the main string_extend folder, and fill it out like so:</p>

                <div class="column2">
                <!-- InstanceBeginEditable name="Code" -->
                <textarea name="code" class="ruby:nogutter:nocontrols" rows="15" cols="60">
                require 'rubygems'
                spec = Gem::Specification.new do |s|
                  s.name = 'string_extend'
                  s.version = '0.0.1'
                  s.summary = "StringExtend adds useful features to the String class"
                  s.files = Dir.glob("**/**/**")
                  s.test_files = Dir.glob("test/*_test.rb")
                  s.autorequire = 'string_extend'
                  s.author = "Satish Talim"
                  s.email = "mail@satishtalim.com"
                  s.has_rdoc = false
                  s.required_ruby_version = '>= 1.8.6'
                end
                </textarea>
                <!-- InstanceEndEditable -->
                </div>

                <p>This is a basic specification file. The specification file is effectively a simple Ruby script that passes information through to <strong>Gem::Specification</strong>. The information it provides is mostly simple, but let's look at a few key areas.<br /><br />First you define the name of the gem, setting it to 'string_extend':</p>

                <div class="column2">
                <!-- InstanceBeginEditable name="Code" -->
                <textarea name="code" class="ruby:nogutter:nocontrols" rows="15" cols="60">
                s.name = 'string_extend'
                </textarea>
                <!-- InstanceEndEditable -->
                </div>

                <p>Next, you define the version number. Typically, version numbers for Ruby projects (and for Ruby itself) contain three parts in order of significance. Early versions of software, before an official release, perhaps, often begin with 0, as in 0.0.1 here:</p>

                <div class="column2">
                <!-- InstanceBeginEditable name="Code" -->
                <textarea name="code" class="ruby:nogutter:nocontrols" rows="15" cols="60">
                s.version = '0.0.1'
                </textarea>
                <!-- InstanceEndEditable -->
                </div>

                <p>The summary line is displayed by gem list, and can be useful to people prior to installing the gem. Simply put together a short description of your library/gem here:</p>

                <div class="column2">
                <!-- InstanceBeginEditable name="Code" -->
                <textarea name="code" class="ruby:nogutter:nocontrols" rows="15" cols="60">
                s.summary = "StringExtend adds useful features to the String class"
                </textarea>
                <!-- InstanceEndEditable -->
                </div>

                <p>The files attribute accepts an array of all the files to include within the gem. In this case you use Dir.glob to get an array of all the files under the current directory:</p>

                <div class="column2">
                <!-- InstanceBeginEditable name="Code" -->
                <textarea name="code" class="ruby:nogutter:nocontrols" rows="15" cols="60">
                s.files = Dir.glob("**/**/**")
                </textarea>
                <!-- InstanceEndEditable -->
                </div>

                <p>However, you could explicitly reference every file in an array in the preceding line.<br /><br />The test_files attribute, like the files attribute, accepts an array of files, in this case associated with tests. You can leave this line intact even if you have no test folder, as Dir.glob will just return an empty array. For example:</p>

                <div class="column2">
                <!-- InstanceBeginEditable name="Code" -->
                <textarea name="code" class="ruby:nogutter:nocontrols" rows="15" cols="60">
                s.test_files = Dir.glob("test/*_test.rb")
                </textarea>
                <!-- InstanceEndEditable -->
                </div>

                <p>The autorequire parameter specifies a file to be loaded automatically with require when the gem is loaded. This parameter isn't particularly important, because users will generally use require 'string_extend' in their code anyway, but if your gem contains multiple Ruby files that need to be loaded, it could come in handy:</p>

                <div class="column2">
                <!-- InstanceBeginEditable name="Code" -->
                <textarea name="code" class="ruby:nogutter:nocontrols" rows="15" cols="60">
                s.autorequire = 'string_extend'
                </textarea>
                <!-- InstanceEndEditable -->
                </div>

                <p>Last, sometimes libraries rely on features in certain versions of Ruby. You can specify the required version of Ruby with the require_ruby_version parameter. If there's no required version, you can simply omit this line:</p>

                <div class="column2">
                <!-- InstanceBeginEditable name="Code" -->
                <textarea name="code" class="ruby:nogutter:nocontrols" rows="15" cols="60">
                s.required_ruby_version = '>= 1.8.6'
                </textarea>
                <!-- InstanceEndEditable -->
                </div>

                <h3>Building the Gem</h3>

                <p>Once the specifications file is complete, building the final .gem file is as simple as:</p>

                <div class="column2">
                <!-- InstanceBeginEditable name="Code" -->
                <textarea name="code" class="ruby:nogutter:nocontrols" rows="15" cols="60">
                gem build &lt;spec file&gt;
                </textarea>
                <!-- InstanceEndEditable -->
                </div>

                <p>In our case:</p>

                <div class="column2">
                <!-- InstanceBeginEditable name="Code" -->
                <textarea name="code" class="ruby:nogutter:nocontrols" rows="15" cols="60">
                gem build string_extend.gemspec
                </textarea>
                <!-- InstanceEndEditable -->
                </div>

                <p>This makes gem create the final gem file, string_extend-0.0.1.gem.<br /><br /><strong>Note</strong>: In future, once you change and update your library, simply update the version numbers, rebuild, and you have a new gem ready to go that can be installed to upgrade the existing installed gem.</p>

                <h3>Distributing a Gem</h3>

                <p>Distributing a gem is easy. You can upload it to a Web site or transfer it in any way you would normally transfer a file. You can then install the gem with gem install by referring to the local file.</p>

                <!--
                <p class="post-footer align-right">
                  <strong>
                    <a href="/satishtalim/ruby_names.html">&lt;Names | </a>
                    <a href="/satishtalim/tutorial.html">TOC | </a>
                    <a href="/satishtalim/writing_own_ruby_methods.html">Writing own Ruby Methods&gt;</a>
                  </strong>
                </p>
                -->
            </div>
            <!-- main inner ends here -->
        </div>

            <div id="rightbar">

            </div>

    <!-- content-wrap ends here -->
    </div>

<!-- wrap ends here -->
</div>

<!-- footer starts here -->
<div id="footer">
    <!-- CHANGE THE FOOTER -->
    <p>&copy; 2006-2021 <strong>rubylearning.github.io - A Ruby Tutorial</strong>&nbsp;&nbsp;Page Updated: 5th Jan. 2021 | Design: <a href="mailto:ealigam@gmail.com">Erwin Aligam</a> | Valid: <a href="http://validator.w3.org/check/referer">XHTML</a> | <a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/">Home</a> | <a href="/privacy.html">Privacy</a> | <a href="/sitemap.html">Sitemap</a></p>

</div>

<!-- SyntaxHighlighter code -->
<script src="/js/shCore.js" type="text/javascript"></script>
<script src="/js/shBrushRuby.js" type="text/javascript"></script>
<script type="text/javascript">
dp.SyntaxHighlighter.HighlightAll('code');
</script>
<!-- SyntaxHighlighter code -->
</body>
</html>
